/*
 * SoftSPI3.c
 *
 *  Created on: Nov 5, 2021
 *      Author: ITry
 */

#include <SoftSPI3.h>

/*
 *  sclk = PC8;
	cs = PC1;
	mosi = miso = PC7;
 */

//SDO/SDI的IO方向(输入/输出)
#define SoftSPISdoIn()	{GPIOC->CRL&=0X0FFFFFFF;GPIOC->CRL|=(uint32_t)8<<28;}
#define SoftSPISdoOut()	{GPIOC->CRL&=0X0FFFFFFF;GPIOC->CRL|=(uint32_t)3<<28;}

#define SetSoftSPISCL() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET)
#define ClrSoftSPISCL() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET)
#define SetSoftSPIMOSI() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET)
#define ClrSoftSPIMOSI() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET)
#define SoftSPI_MISO_H() (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == GPIO_PIN_SET)

/*
 ** 返回值 : temp--SPI读取的一字节数据
 ** 描  述 : 下降沿读数据，每次读取 1 bit
*/
uint8_t SPI3_Read_OneByte(void)
{
  uint8_t i;
  uint8_t temp = 0;
  for (i = 0; i < 8; i++)
  {
    //读取MISO 8次输入的值，存入temp。之所以不放在“SCK = 0”语句之后的位置是因为：
    //读取最后1byte的最后一位(即LSB)之后，不能再左移了
    temp <<= 1;
    SetSoftSPISCL();
    SoftSPISdoIn();
    if (SoftSPI_MISO_H()) //读取最高位，保存至最末尾，通过左移位完成读整个字节
      temp |= 0x01;
    else
      temp &= ~0x01;
    ClrSoftSPISCL();
  }
  return temp;
}

/*
** 参  数    : u8_writedata--SPI写入的一字节数据
** 描  述    : 上升沿写数据，每次写入 1 bit
*/
void SPI3_Write_OneByte(uint8_t u8_writedata)
{
  uint8_t i;
  SoftSPISdoOut();
  for (i = 0; i < 8; i++)
  {
    if (u8_writedata & 0x80) //判断最高位，总是发送最高位
    {
    	SetSoftSPIMOSI(); //MOSI输出1，数据总线准备数据1
    }
    else
    {
    	ClrSoftSPIMOSI();//MOSI输出0，数据总线准备数据0
    }
    SetSoftSPISCL(); //上升沿来了(SCK从0-->1)，数据总线上的数据写入到器件
    u8_writedata <<= 1; //左移抛弃已经输出的最高位
    ClrSoftSPISCL(); //拉低SCK信号，初始化为0
  }
}
